package com.ciwong.libs.audio.play;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

import com.ciwong.libs.utils.CWLog;

public class PlayPcmThread extends Thread
{
    public static final String TAG = "PlayPcmThread";

    private String mPath;

    private OnPlayListener mOnPlayListener;

    private boolean mRun, isPuase;

    private long mOffset = 0;

    private int mLen = -1;

    private Object callbackTag;

    public PlayPcmThread(String path, Object tag)
    {
        mPath = path;
        callbackTag = tag;
    }

    /**
     * 设置播放监听接口
     * 
     * @param listener
     *            {@link OnPlayListener}
     */
    public void setOnPlayerListener(OnPlayListener listener)
    {
        mOnPlayListener = listener;
    }

    /**
     * 恢复播放
     */
    public void resumePlay()
    {
        if (isPuase)
        {
            isPuase = false;
            synchronized (this)
            {
                notify();
            }
        }
    }

    /**
     * 暂停
     * 
     */
    public void pausePlay()
    {
        synchronized (this)
        {
            isPuase = true;
        }
    }

    public void stopPlay()
    {
        CWLog.i("debug", "stopPlay");
        mRun = false;
    }

    @Override
    public void run()
    {
        mRun = true;
        int minBufferSize = AudioTrack.getMinBufferSize(16000,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, 16000,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                minBufferSize, AudioTrack.MODE_STREAM);
        InputStream is = null;
        try
        {
            if (track.getState() == AudioTrack.STATE_INITIALIZED)
            {
                if (mOnPlayListener != null)
                {
                    mOnPlayListener.onReadPlayer(0, callbackTag);
                }
                track.play();
                byte[] buffer = new byte[minBufferSize];
                is = new FileInputStream(mPath);
                while (mOffset > 0)
                {
                    long skipcount = is.skip(mOffset);
                    mOffset -= skipcount;
                }
                if (mOnPlayListener != null)
                {
                    mOnPlayListener.onPlayStart(mPath);
                }
                while (mRun)
                {
                    synchronized (this)
                    {
                        if (isPuase)
                        {
                            this.wait();
                        }
                    }
                    int count = is.read(buffer);
                    if (count == -1 || mLen == 0)
                    {
                        break;
                    }
                    if (mLen != -1)
                    {
                        if (count <= mLen)
                        {
                            mLen -= count;
                        }
                        else
                        {
                            count = mLen;
                            mLen = 0;
                        }
                    }
                    track.write(buffer, 0, count);
                }
                if (mLen != -1 && mLen < 20 * 320)
                {
                    byte[] zero = new byte[6400 - mLen];
                    track.write(zero, 0, zero.length);
                }
                if (mOnPlayListener != null)
                {
                    mOnPlayListener.stop(mPath);
                }
            }
            else
            {
                if (mOnPlayListener != null)
                {
                    mOnPlayListener.onError(AudioPlayer.PLAY_ERROR_INIT,
                            callbackTag);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            if (mOnPlayListener != null)
            {
                mOnPlayListener
                        .onError(
                                (e instanceof FileNotFoundException) ? AudioPlayer.PLAY_ERROR_FILE_NOT_EXISTS
                                        : AudioPlayer.PLAY_ERROR, callbackTag);
            }
        }
        finally
        {
            if (track != null)
            {
                track.stop();
                track.release();
                track = null;
            }
            if (is != null)
            {
                try
                {
                    is.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
